#include "clientmessagehandler.h"
#include <QImage>
#include "./entities/messageentities.h"
#include "./tools/data/contentdealer.h"

ClientMessageHandler ClientMessageHandler::m_instance;
ClientMessageHandler& ClientMessageHandler::getInstance()
{
    return m_instance;
}

ClientMessageHandler::ClientMessageHandler(QObject *parent): QObject{parent} {}

ClientMessageHandler::~ClientMessageHandler()
{

}


void ClientMessageHandler::sendLoginRequestMessage(const QString userId, const QString password)
{
    LoginRequestMessage loginRequestMessage(userId, password);
    QByteArray data = ContentDealer::JsonPack(loginRequestMessage);
    emit dataReadyToSend(data);
}

void ClientMessageHandler::sendRegisterRequestMessage(const QString email, const QString nickname, const QString password)
{
    RegisterRequestMessage registerRequestMessage(email, nickname, password);
    QByteArray data = ContentDealer::JsonPack(registerRequestMessage);
    emit dataReadyToSend(data);
}

void ClientMessageHandler::sendLogoutRequestMessage(const QString userId)
{
    LogoutRequestMessage logoutRequestMessage(userId);
    QByteArray data = ContentDealer::JsonPack(logoutRequestMessage);
    emit dataReadyToSend(data);
}

void ClientMessageHandler::sendSearchNewUserRequestMessage(const QString newUserId)
{
    SearchUserRequestMessage searchRequestMessage(newUserId);
    QByteArray data = ContentDealer::JsonPack(searchRequestMessage);
    emit dataReadyToSend(data);
}

void ClientMessageHandler::sendApplyFriendRequestMessage(const QString userId, const QString friendId,
                                   const QString alias, const QString verifyInfo)
{
    ApplyFriendRequestMessageToServer applyFriendRequestMessage(userId, friendId, alias, verifyInfo);
    QByteArray data = ContentDealer::JsonPack(applyFriendRequestMessage);
    emit dataReadyToSend(data);
}
\
void ClientMessageHandler::sendRequestBufferDataMessage(QString userId)
{
    RequestBufferDataMessage requestBufferDataMessage(userId);
    QByteArray data = ContentDealer::JsonPack(requestBufferDataMessage);
    emit dataReadyToSend(data);
}

void ClientMessageHandler::sendApplyFriendResponseMessage(const FriendVerifyStatus status, const QString alias, const int id)
{
    QString friendStatus = JsonValue::STATUS_REJECTED;
    if (status == FriendVerifyStatus::Accpeted)
    {
        friendStatus = JsonValue::STATUS_ACCEPTED;
    }
    ApplyFriendResponseMessageToServer afrm(friendStatus, alias, id);
    QByteArray data = ContentDealer::JsonPack(afrm);
    emit dataReadyToSend(data);
}

void ClientMessageHandler::sendChatMessage(const QString userId, const QString friendId,
                                           const QString msg, const QDateTime sendTime)
{
    ChatMessageToServer cmts(userId, friendId, msg, sendTime.toString(Qt::ISODate));
    QByteArray data = ContentDealer::JsonPack(cmts);
    emit dataReadyToSend(data);
}

// 发送视频通话请求
void ClientMessageHandler::sendVideoRequestMessage(const QString userId,
                             const QString userIp, const QString friendId)
{
    VideoRequestToServer vrts(userId, userIp, friendId);
    QByteArray data = ContentDealer::JsonPack(vrts);
    emit dataReadyToSend(data);
}

// 发送视频通话请求回复结果
void ClientMessageHandler::sendVideoResponseMessge(const UserId responseUserId,
    const FriendId requestUserId, const Status status, const Ip responseUserIp)
{
    VideoResponseToServer vrts(responseUserId, requestUserId, status, responseUserIp);
    QByteArray data = ContentDealer::JsonPack(vrts);
    emit dataReadyToSend(data);
}

void ClientMessageHandler::handleByteData(const QByteArray originData)
{
    QByteArray unpackedData;
    ContentType ct = ContentDealer::Unpack(originData, unpackedData);
    switch (ct)
    {
        case ContentType::MESSAGE:
        {
            handleMessage(unpackedData);
            break;
        }
        case ContentType::IMAGE:
        {
            handleImage(unpackedData);
            break;
        }
        case ContentType::OTHER:
        {
            break;
        }
    }
}


// private

void ClientMessageHandler::handleMessage(const QByteArray& unpackedData)
{
    QJsonObject jsonObj;
    MessageType mt = ContentDealer::GetMessageType(unpackedData, jsonObj);
    switch (mt) {
    case MessageType::LoginResponse: {  // 登录回复
        qDebug() << "收到登录回复";
        LoginResponseMessage lrm(jsonObj);
        emit getLoginResponse(lrm.getStatus(), lrm.getReason());
        break;
    }
    case MessageType::RegisterResponse: {   // 注册回复
        qDebug() << "收到注册回复";
        RegisterResponseMessage rrm(jsonObj);
        emit getRegisterResponse(rrm.getStatus(), rrm.getReason(), rrm.getUserId());
        break;
    }
    case MessageType::LogoutResponse: { // 登出回复
        qDebug() << "收到登出回复";
        LogoutResponseMessage lrm(jsonObj);
        emit getLogoutResponse(lrm.getStatus(), lrm.getReason());
        break;
    }
    case MessageType::SearchUserResponse: { // 搜索用户回复
        qDebug() << "收到搜索用户回复";
        SearchUserResponseMessage surm(jsonObj);
        emit getSearchUserResponse(surm.getStatus(), surm.getReason(), surm.getUserId(), surm.getNickname());
        break;
    }
    case MessageType::ApplyFriendRequestToClient: { // 新好友申请请求
        qDebug() << "收到新好友申请";
        // 1. 发给DBService线程存储，同时发给UI线程渲染
        ApplyFriendRequestMessageToClient afrmtc(jsonObj);
        QDateTime createTime = QDateTime::fromString(afrmtc.getApplyTime(), Qt::ISODate);  // 使用与存储时相同的格式
        emit getApplyFriendRequestToClient(afrmtc.getReceiverId(), afrmtc.getApplicantId(), afrmtc.getNickname(), afrmtc.getVerifyInfo(), createTime, afrmtc.getId());
        qDebug() << "发送新好友申请信号完毕";
        // 2. 告诉服务器收到这个信号了
        GetApplicationFromServer gafs(afrmtc.getId());
        QByteArray data = ContentDealer::JsonPack(gafs);
        emit dataReadyToSend(data);

        break;
    }
    case MessageType::ApplyFriendResponseToClient: {    // 之前发送的好友申请有审核结果了
        qDebug() << "收到申请好友审核结果";
        // 1. 发给DBService线程存储，同时发给UI线程渲染
        ApplyFriendResponseMessageToClient afrmtc(jsonObj);

        QDateTime createTime = QDateTime::fromString(afrmtc.getCreateTime(), Qt::ISODate);  // 使用与存储时相同的格式
        emit getApplyFriendResponseToClient(afrmtc.getFriendId(), afrmtc.getNickname(),
                afrmtc.getStatus(), afrmtc.getAlias(), createTime);
        // 2. 告诉服务器收到这个消息了
        GetApplicationResultFromServer garfs(afrmtc.getId());
        QByteArray data = ContentDealer::JsonPack(garfs);
        emit dataReadyToSend(data);

        break;
    }
    case MessageType::ChatMessageToClient: {    // 收到其他用户发送的聊天消息
        qDebug() << "收到其他用户发来的聊天消息了";
        // 1. 发给UI线程渲染和DBService线程存储
        ChatMessageToClient gmtc(jsonObj);
        QDateTime sendTime = QDateTime::fromString(gmtc.getSendTime(), Qt::ISODate);  // 使用与存储时相同的格式
        emit getNewChatMsg(gmtc.getSenderId(), gmtc.getChatMessage(), sendTime);
        qDebug() << gmtc.getChatMessage();
        // 2. 告诉服务器收到这个消息了
        GetChatMessageFromServer gcmfs(gmtc.getId());
        QByteArray data = ContentDealer::JsonPack(gcmfs);
        emit dataReadyToSend(data);
        break;
    }
    case MessageType::VideoRequestToClient: {   // 收到服务器转发的视频通话请求
        qDebug() << "收到服务器转发的视频通话请求";
        VideoRequestToClient vrtc(jsonObj);
        emit getVideoRequest(vrtc.getRequestUserId(), vrtc.getRequestUserIp());
        break;
    }
    case MessageType::VideoResponseToClient: {  // 服务器转发给客户端视频通话请求结果
        qDebug() << "收到服务器转发给客户端视频通话请求结果";
        VideoResponseToClient vrtc(jsonObj);
        emit getVideoResponse(vrtc.getRequestUserId(), vrtc.getResponseUserId(),
            vrtc.getStatus(), vrtc.getResponseUserIp());
        break;
    }
    default:
        break;
    }
}

void ClientMessageHandler::handleImage(const QByteArray& unpackedData)
{
    QImage image = QImage::fromData(unpackedData, "BMP");

}
